package git.soulbgm.thread;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 线程池管理器
 *
 * <p>管理应用程序中使用的线程池，提供统一的线程资源管理。
 * 根据配置创建和维护不同用途的线程池，确保线程资源的合理利用。</p>
 *
 * <p>功能特性：</p>
 * <ul>
 *   <li>创建和管理多个线程池</li>
 *   <li>支持不同类型的任务调度</li>
 *   <li>提供线程池监控功能</li>
 *   <li>支持优雅关闭</li>
 * </ul>
 *
 * @author soulbgm
 * @version 1.0
 * @since 1.0
 */
public class ThreadPoolManager {
    private static final Logger logger = LoggerFactory.getLogger(ThreadPoolManager.class);

    /**
     * CPU核心数
     */
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    /**
     * 转发线程池核心线程数
     */
    private static final int FORWARD_CORE_SIZE = Math.max(4, CPU_COUNT);
    /**
     * 转发线程池最大线程数
     */
    private static final int FORWARD_MAX_SIZE = FORWARD_CORE_SIZE * 2;
    /**
     * 转发线程池队列容量
     */
    private static final int FORWARD_QUEUE_SIZE = 10000;
    /**
     * 转发线程空闲超时时间（秒）
     */
    private static final long FORWARD_KEEP_ALIVE = 60L;

    /**
     * 调度线程池大小
     */
    private static final int SCHEDULE_POOL_SIZE = 3;

    /**
     * 转发线程池
     */
    private final ThreadPoolExecutor forwardExecutor;
    /**
     * 调度线程池
     */
    private final ScheduledExecutorService scheduleExecutor;

    /**
     * 创建线程池管理器实例
     */
    public ThreadPoolManager() {
        // 创建转发线程池
        forwardExecutor = new ThreadPoolExecutor(
                FORWARD_CORE_SIZE,
                FORWARD_MAX_SIZE,
                FORWARD_KEEP_ALIVE,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(FORWARD_QUEUE_SIZE),
                new NamedThreadFactory("UDP-Forward"),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
        forwardExecutor.allowCoreThreadTimeOut(true);

        // 创建调度线程池
        scheduleExecutor = new ScheduledThreadPoolExecutor(
                SCHEDULE_POOL_SIZE,
                new NamedThreadFactory("UDP-Schedule"),
                new ThreadPoolExecutor.AbortPolicy()
        );

        // 配置调度线程池
        ((ScheduledThreadPoolExecutor) scheduleExecutor).setRemoveOnCancelPolicy(true);
        ((ScheduledThreadPoolExecutor) scheduleExecutor).setExecuteExistingDelayedTasksAfterShutdownPolicy(false);

        // 启动线程池监控
        startMonitoring();
    }

    /**
     * 获取转发线程池
     */
    public ThreadPoolExecutor getForwardExecutor() {
        return forwardExecutor;
    }

    /**
     * 获取调度线程池
     */
    public ScheduledExecutorService getScheduleExecutor() {
        return scheduleExecutor;
    }

    /**
     * 启动线程池监控
     */
    private void startMonitoring() {
        scheduleExecutor.scheduleAtFixedRate(() -> {
            try {
                logPoolStats();
            } catch (Exception e) {
                logger.error("监控线程池状态出错", e);
            }
        }, 1, 1, TimeUnit.MINUTES);
    }

    /**
     * 记录线程池状态
     */
    private void logPoolStats() {
        logger.info("转发线程池状态 - 活跃线程: {}/{}, 当前线程: {}, 完成任务: {}, 队列大小: {}/{}",
                forwardExecutor.getActiveCount(),
                forwardExecutor.getMaximumPoolSize(),
                forwardExecutor.getPoolSize(),
                forwardExecutor.getCompletedTaskCount(),
                forwardExecutor.getQueue().size(),
                FORWARD_QUEUE_SIZE
        );
    }

    /**
     * 等待终止超时时间 单位秒
     */
    private static final int AWAIT_TERMINATION_TIMEOUT = 5;

    /**
     * 关闭所有线程池
     */
    public void shutdown() {
        logger.info("正在关闭线程池...");

        // 关闭调度线程池
        scheduleExecutor.shutdown();
        try {
            if (!scheduleExecutor.awaitTermination(AWAIT_TERMINATION_TIMEOUT, TimeUnit.SECONDS)) {
                scheduleExecutor.shutdownNow();
            }
        } catch (InterruptedException e) {
            scheduleExecutor.shutdownNow();
            Thread.currentThread().interrupt();
        }

        // 关闭转发线程池
        forwardExecutor.shutdown();
        try {
            if (!forwardExecutor.awaitTermination(AWAIT_TERMINATION_TIMEOUT, TimeUnit.SECONDS)) {
                forwardExecutor.shutdownNow();
            }
        } catch (InterruptedException e) {
            forwardExecutor.shutdownNow();
            Thread.currentThread().interrupt();
        }

        logger.info("线程池已关闭");
    }

    /**
     * 命名线程工厂
     */
    private static class NamedThreadFactory implements ThreadFactory {
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        NamedThreadFactory(String prefix) {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
            namePrefix = prefix + "-";
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
            t.setDaemon(true);
            if (t.getPriority() != Thread.NORM_PRIORITY) {
                t.setPriority(Thread.NORM_PRIORITY);
            }
            return t;
        }
    }
} 